package pimmodel;

/**
 * Die Klasse Adresse:<br>
 * Wird fuer die Klasse Kontakt benoetigt, da die Adressen durch eine Liste verwaltet werden.
 *  
 * @author Thomas Schoenfeld
 * @version (20120902_01)
 *
 */
public class Adresse implements IAdresse {

	// Serialisierungs-UID
	private static	final	long	serialVersionUID	= 1L;
	
	
	
	// Meldungskonstanten
	
	private	static	final	String	HAUSNUMMER			= "Die uebergebene Hausnummer ist negativ.";
	private	static	final	String	PLZ					= "Die uebergebene Postleitzahl ist kein gueltiger String.";	
	private	static	final	String	STRASSE				= "Die uebergebene Strasse ist kein gueltiger String.";
	private	static	final	String	ORT					= "Der uebergebene Ort ist kein gueltiger String.";
	private	static	final	String	LAND				= "Das uebergebene Land ist kein gueltiger String.";
	private	static	final	String	IADRESSE			= "Das uebergebene Objekt ist nicht vom Typ IAdresse.";
	
	
	
	// Instanzvariablen
	
	private					String	hausnummer;	
	private 				String	strasse;
	private 				String	plz;	
	private 				String	ort;
	private 				String	land;
	
	
	
	/**
	 * Standardkonstruktor der Klasse Adresse.
	 */
	public Adresse() {
		
		this.hausnummer	= "";
		this.strasse	= "";
		this.plz		= "";
		this.ort		= "";
		this.land		= "";
		
	}
	
	/**
	 * Konstruktor der Klasse Adresse.
	 * 
	 * @param strasse	die Strasse
	 * @param hausnr	die Hausnummer
	 * @param plz		die Postleitzahl
	 * @param ort		der Ort
	 * @param land		das Land
	 */
	public Adresse( final String strasse, final String hausnr, final String plz, final String ort, final String land ) {
					
		setStrasse( strasse );
		setHausnummer( hausnr );
		setPlz( plz );
		setOrt( ort );
		setLand( land );
		
	}
	
	/**
	 * Kopierkonstruktor der Klasse Adresse.
	 * 
	 * @param 	adresse	die zu kopierende Adresse
	 * 
	 * @throws IllegalArgumentException falls das uebergebene Objekt nicht vom Typ IAdresse ist.
	 */
	public Adresse( final IAdresse adresse ) {
		
		if ( !( adresse instanceof Adresse ) )
			throw new IllegalArgumentException( IADRESSE );
		
		setStrasse( adresse.getStrasse() );
		setHausnummer( adresse.getHausnummer() );
		setPlz( adresse.getPlz() );
		setOrt( adresse.getOrt() );
		setLand( adresse.getLand() );
		
	}

	
	
	// Getter und Setter Methoden
	
	/* (non-Javadoc)
	 * @see pimmodel.IAdresse#getHausnummer()
	 */
	@Override
	public String getHausnummer() {
		
		return hausnummer;
		
	}

	/* (non-Javadoc)
	 * @see pimmodel.IAdresse#setHausnummer(int)
	 */
	@Override
	public void setHausnummer( final String hausnummer ) {
		
		if ( !( hausnummer instanceof String ) )
			throw new IllegalArgumentException( HAUSNUMMER );
		
		this.hausnummer = hausnummer.trim();
		
	}

	/* (non-Javadoc)
	 * @see pimmodel.IAdresse#getPlz()
	 */
	@Override
	public String getPlz() {
		
		return plz;
		
	}

	/* (non-Javadoc)
	 * @see pimmodel.IAdresse#setPlz(java.lang.String)
	 */
	@Override
	public void setPlz( final String plz ) {
		
		if ( !( plz instanceof String ) )
			throw new IllegalArgumentException( PLZ );
		
		this.plz = plz.trim();
		
	}

	/* (non-Javadoc)
	 * @see pimmodel.IAdresse#getStrasse()
	 */
	@Override
	public String getStrasse() {
		
		return strasse;
		
	}

	/* (non-Javadoc)
	 * @see pimmodel.IAdresse#setStrasse(java.lang.String)
	 */
	@Override
	public void setStrasse( final String strasse ) {
		
		if ( !( strasse instanceof String ) )
			throw new IllegalArgumentException( STRASSE );
		
		this.strasse = strasse.trim();
		
	}

	/* (non-Javadoc)
	 * @see pimmodel.IAdresse#getOrt()
	 */
	@Override
	public String getOrt() {
		
		return ort;
		
	}

	/* (non-Javadoc)
	 * @see pimmodel.IAdresse#setOrt(java.lang.String)
	 */
	@Override
	public void setOrt( final String ort ) {
		
		if ( !( ort instanceof String ) )
			throw new IllegalArgumentException( ORT );
		
		this.ort = ort.trim();
		
	}

	/* (non-Javadoc)
	 * @see pimmodel.IAdresse#getLand()
	 */
	@Override
	public String getLand() {
		
		return land;
		
	}

	/* (non-Javadoc)
	 * @see pimmodel.IAdresse#setLand(java.lang.String)
	 */
	@Override
	public void setLand( final String land ) {
		
		if ( !( land instanceof String ) )
			throw new IllegalArgumentException( LAND );
		
		this.land = land.trim();
		
	}

	
	
	// sonstige Methoden

	/* (non-Javadoc)
	 * @see pimmodel.IAdresse#toString()
	 */
	@Override
	public String toString() {
		
		return "Adresse [Strasse = " + strasse + ", Hausnummer = " + hausnummer +
				", PLZ = " + plz + ", Ort = " + ort + ", Land = " + land + "]";
		
	}	
	
	/* (non-Javadoc)
	 * @see pimmodel.IAdresse#hashCode()
	 */
	@Override
	public int hashCode() {
		
		final int prime = 31;
		
		int result = 1;
		
		result = prime * result + ( ( hausnummer == null ) ? 0 : hausnummer.hashCode() );
		result = prime * result + ( ( land == null ) ? 0 : land.hashCode() );
		result = prime * result + ( ( ort == null ) ? 0 : ort.hashCode() );
		result = prime * result + ( ( plz == null ) ? 0 : plz.hashCode() );
		result = prime * result + ( (strasse == null) ? 0 : strasse.hashCode() );
		
		return result;
		
	}

	/* (non-Javadoc)
	 * @see pimmodel.IAdresse#equals(java.lang.Object)
	 */
	@Override
	public boolean equals( final Object obj ) {
		
		if ( this == obj )
			return true;
		if ( obj == null )
			return false;
		if ( getClass() != obj.getClass() )
			return false;
		IAdresse other = ( IAdresse ) obj;
		if ( hausnummer == null ) {
			if ( other.getHausnummer() != null )
				return false;
		}
		else if ( !hausnummer.equals( other.getHausnummer() ) )
			return false;
		if ( land == null ) {
			if ( other.getLand() != null )
				return false;
		}
		else if ( !land.equals( other.getLand() ) )
			return false;
		if ( ort == null ) {
			if ( other.getOrt() != null )
				return false;
		}
		else if ( !ort.equals( other.getOrt() ) )
			return false;
		if ( plz == null ) {
			if ( other.getPlz() != null )
				return false;
		}
		else if ( !plz.equals( other.getPlz() ) )
			return false;
		if ( strasse == null ) {
			if ( other.getStrasse() != null )
				return false;
		}
		else if ( !strasse.equals( other.getStrasse() ) )
			return false;
		return true;
	}	
	
	/**
	 * compareTo	erlaubt einen lexikographischen Groessenvergleich mit einer anderen Adresse
	 * 
	 * @param		adresse	die zu vergleichende Adresse
	 * 
	 * @return		-1, falls die aktuelle Adresse lexikographisch kleiner,<br>
	 * 				 1, falls sie groesser und<br>
	 * 				 0, gleich der uebergebenen Adresse ist
	 * 
	 * @throws	IllegalArgumentException falls das uebergebene Objekt nicht vom Typ IAdresse ist.
	 */
	@Override
	public int compareTo( IAdresse adresse ) {
		
		if ( ! ( adresse instanceof IAdresse ) )
			throw new IllegalArgumentException( IADRESSE );
		
		if ( this.land.compareTo( adresse.getLand() ) < 0 )
			return -1;
		if ( this.land.compareTo( adresse.getLand() ) > 0 )
			return 1;
		if ( this.plz.compareTo( adresse.getPlz() ) < 0 )
			return -1;
		if ( this.plz.compareTo( adresse.getPlz() ) > 0 )
			return 1;
		if ( this.strasse.compareTo( adresse.getStrasse() ) < 0 )
			return -1;
		if ( this.strasse.compareTo( adresse.getStrasse() ) > 0 )
			return 1;
		if ( this.hausnummer.compareTo( adresse.getHausnummer() ) < 0 )
			return -1;
		if ( this.hausnummer.compareTo( adresse.getHausnummer() ) > 0 )
			return 1;
		
		return 0;
		
	}

}
